home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-15 | 26.8 KB | 922 lines | [TEXT/MPS ] |
- // AGSampleCode.c
- // Copyright 1996, Apple Computer, Inc.
- // Date: 23-Jan-96
- // Author: guideWorks, LLC
- // Web: http://www.guideworks.com
- // EMail: powers@guideworks.com
- //
- // This file contains the Apple Guide integration code for the application.
- // See the AGSampleGuide for more information.
-
- // AGSInstallCoachHandler
- // Install the coach mark handler.
-
- // AGSRemoveCoachHandler
- // Remove the coach mark handler.
-
- // AGSCoachReplyProc
- // Return the global rectangle of an object in the document window.
-
- // AGSInstallContextHandler
- // Install the context check handler.
-
- // AGSRemoveContextHandler
- // Remove the context check handler.
-
- // AGSContextReplyProc
- // Reply to context checks.
-
- // AGSInstallAEHandler
- // Install the Apple event handler.
-
- // AGSRemoveAEHandler
- // Remove the Apple event handler.
-
- // AGSHandleAEvents
- // Handles the custom events.
-
- // AGSOpenGuide
- // Open the guide file in its default view.
-
- // AGSOpenGuideWithSearch
- // Open the guide file with a search.
-
- // AGSInstallASCoachHandlers
- // Install the handlers for AppleScript Coach
-
- // AGSRemoveASCoachHandlers
- // Remove the handlers for AppleScript Coach
-
- // AGSHandleGetData
- // Return a reply to the Get Data Apple Event for the requested data.
-
- // AGSGetDataItemCoachRect
- // Get the property data for the item and return it in the result parameter.
-
- // AGSCoachItemAccessor
- // Return the token for the coach item identifier.
-
- // AGSCoachItemPropertyAccessor
- // Return a token representing the property for the coach item.
-
- // ---------- Headers -----------------------------------------------------
-
- #include "AGSampleCode.h" // Headers for the Apple Guide sample code.
-
- // ---------- Globals -----------------------------------------------------
-
- AGCoachRefNum gCoachRefNum;
- AGContextRefNum gContextRefNum;
- AGRefNum gGuideRefNum;
- FileRecHndl ghFileRec;
- // ---------- General Functions -------------------------------------------
-
- // ------------------------------------------------------------------------
- // AGSInstall
- // Install all handlers.
-
- void
- AGSInstall()
- {
- AGSInstallCoachHandler();
- AGSInstallContextHandler();
- AGSInstallASCoachHandlers();
- AGSInstallAEHandler();
- }
-
- // ------------------------------------------------------------------------
- // AGSRemove
- // Remove all handlers.
-
- void
- AGSRemove()
- {
- AGSRemoveCoachHandler();
- AGSRemoveContextHandler();
- AGSRemoveASCoachHandlers();
- AGSRemoveAEHandler();
- }
-
- // ---------- Object Coach Functions --------------------------------------
-
- // ------------------------------------------------------------------------
- // AGSInstallCoachHandler
- // Install the coach mark handler.
-
- OSErr
- AGSInstallCoachHandler()
- {
- long myRefCon=0;
-
- return AGInstallCoachHandler(NewCoachReplyProc(AGSCoachReplyProc),
- myRefCon, &gCoachRefNum);
- }
-
- // ------------------------------------------------------------------------
- // AGSRemoveCoachHandler
- // Remove the coach mark handler.
-
- OSErr
- AGSRemoveCoachHandler()
- {
- return AGRemoveCoachHandler(&gCoachRefNum);
- }
-
- // ------------------------------------------------------------------------
- // AGSCoachReplyProc
- // Reply to object coach marks defined in AGSample Guide and sent by Apple Guide.
- // Return the global rectangle of the object whose name is given.
- // This is a reply function installed by AGSInstallCoachHandler.
- // Guide Script:
- // <Define Object Coach> "Coach open guide button", 'AGS2', REDCIRCLE, "1001"
- // <Define Object Coach> "Coach open guide with search button", 'AGS2', REDCIRCLE, "1002"
- // <Define Object Coach> "Coach checkbox", 'AGS2', REDCIRCLE, "2001"
- // For this sample application:
- // target app is 'AGS2' (kAGSTargetAppSignature).
-
- pascal OSErr
- AGSCoachReplyProc(Rect* pRect, Ptr name, long refCon)
- {
- Boolean isFound=false;
- WindowPtr pWin;
- // The object name is passed as a string. Our "name" is the control identifier.
- // <Define Object Coach> "Coach Open Guide button", 'AGS2', REDCIRCLE, "1001"
- // <Define Object Coach> "Coach Checkbox", 'AGS2', REDCIRCLE, "2001"
- // Apple guide passes the name as a null-terminated c-string.
- // If we use 4-character names,
- // then we can cast the name as an OSType to make comparisons easier.
- OSType myNameAsOSType=*((OSType*)name);
- // Or we can convert the c-string to a decimal number
- // using an Apps-To-Go function.
- long myNameAsDecNumber = c2dec(name, nil);
- // Initialize the rect to an empty rect.
- Rect globalRect;
- SetRect(&globalRect, 0, 0, 0, 0);
- // Check each document window.
- for(pWin=nil; (pWin=GetNextDocumentWindow(pWin, 0))!=nil && !isFound;)
- if(pWin)
- if(((WindowPeek)pWin)->hilited)
- {
- // We only coach if the window is front (active).
- // Get the window content rectangle.
- Rect winRect = GetWindowContentRect(pWin);
- // Get the control whose ID==myNameAsDecNumber.
- ControlHandle hCtrl;
- (void) CNum2Ctl(pWin, myNameAsDecNumber, &hCtrl);
- if(hCtrl)
- {
- // Get the local rect of the control and convert to global.
- Rect ctrlRect = (**hCtrl).contrlRect;
- globalRect.top = ctrlRect.top + winRect.top;
- globalRect.left = ctrlRect.left + winRect.left;
- globalRect.bottom = winRect.top + ctrlRect.bottom;
- globalRect.right = winRect.left + ctrlRect.right;
- isFound = true;
- }
- }
- // Return the rectangle for the object.
- *pRect = globalRect;
- // If you want the coach mark drawn, return noErr.
- // If you don't want the coach mark drawn, return kAGErrItemNotFound.
- return (isFound)?noErr:kAGErrItemNotFound;
- }
-
- // ---------- Context Functions -------------------------------------------
-
- // ------------------------------------------------------------------------
- // AGSInstallContextHandler
- // Install the context check handler.
-
- OSErr
- AGSInstallContextHandler()
- {
- AEEventID contextEventID=kAGSContextCodeResSpec;
- long myRefCon=nil;
-
- return AGInstallContextHandler(NewContextReplyProc(AGSContextReplyProc),
- contextEventID, myRefCon, &gContextRefNum);
- }
-
- // ------------------------------------------------------------------------
- // AGSRemoveContextHandler
- // Remove the context check handler.
-
- OSErr
- AGSRemoveContextHandler()
- {
- return AGRemoveContextHandler(&gContextRefNum);
- }
-
- // ------------------------------------------------------------------------
- // AGSContextReplyProc
- // Reply to context checks defined in AGSample Guide and sent by Apple Guide.
- // This is a reply function installed by AGSInstallContextHandler.
- // Guide Script:
- // <Define Context Check> "IsAnyDocumentOpen", 'agsd', 'AGS2', LONG:1, LONG:0
- // <Define Context Check> "IsThisControlFront", 'agsd', 'AGS2', LONG:2, LONG
- // <Define Context Check> "IsThisControlTrue", 'agsd', 'AGS2', LONG:3, LONG
- // For this sample application:
- // target app is 'AGS2' (kAGSTargetAppSignature).
- // code resource spec is 'agsd' (kAGSContextCodeResSpec).
- //
- // We install separate handlers, each with its own event ID.
- // However, for this sample, we use a single handler
- // and pass a selector in the input data.
-
- pascal OSErr
- AGSContextReplyProc(Ptr pInputData, Size inputDataSize,
- Ptr *ppOutputData, Size *pOutputDataSize,
- AGAppInfoHdl hAppInfo)
- {
- Ptr pResult;
- WindowPtr pWin;
- ControlHandle hCtrl;
- OSErr err=noErr;
- Boolean result=false;
- Boolean isFound=false;
- InputDataPtr pMyInputData=(InputDataPtr)pInputData;
-
- // See what is to be checked.
- if(inputDataSize==sizeof(InputDataType))
- {
- switch (pMyInputData->checkSelector)
- {
- case kAGSCheckSelectorDocumentAny:
- // Is any document open?
- result = (GetWindowCount(false, false, false)>0);
- break;
- case kAGSCheckSelectorControlFront:
- // Is this control front?
- // Check each document window.
- for(pWin=nil; (pWin=GetNextDocumentWindow(pWin, 0))!=nil && !isFound;)
- if(pWin)
- {
- // See if the control is in this document window.
- (void) CNum2Ctl(pWin, pMyInputData->itemIdentifier, &hCtrl);
- if(hCtrl)
- {
- // Control is in this window, is window front?
- result = ((WindowPeek)pWin)->hilited;
- isFound = true;
- }
- }
- break;
- case kAGSCheckSelectorControlTrue:
- // Is this control true?
- // Check each document window.
- for(pWin=nil; (pWin=GetNextDocumentWindow(pWin, 0))!=nil && !isFound;)
- if(pWin)
- {
- // See if the control is in this document window.
- (void) CNum2Ctl(pWin, pMyInputData->itemIdentifier, &hCtrl);
- if(hCtrl)
- {
- // Get value of the control.
- result = ((**hCtrl).contrlValue==1);
- isFound = true;
- }
- }
- break;
- default:
- break;
- }
- }
- // Convert result to a form that Apple Guide understands.
- pResult = NewPtr(sizeof(Boolean));
- if (pResult)
- {
- BlockMoveData(&result, pResult, sizeof(Boolean));
- *ppOutputData = pResult;
- *pOutputDataSize = sizeof(Boolean);
- }
- else
- err = MemError();
-
- return err;
- }
-
- // ---------- Apple event Functions ---------------------------------------
-
- // ------------------------------------------------------------------------
- // AGSInstallAEHandler
- // Install the Apple event handler.
-
- OSErr
- AGSInstallAEHandler()
- {
- long myRefCon=0;
-
- return AEInstallEventHandler(kAGSAEventClass,
- typeWildCard,
- NewAEEventHandlerProc(AGSHandleAEvents),
- myRefCon, false);
- }
-
- // ------------------------------------------------------------------------
- // AGSRemoveAEHandler
- // Remove the Apple event handler.
-
- OSErr
- AGSRemoveAEHandler()
- {
- return AERemoveEventHandler(kAGSAEventClass, typeWildCard, false, false);
- }
-
- // ------------------------------------------------------------------------
- // AGSHandleAEvents
- // Handles the custom events defined in AGSample Guide and sent by Apple Guide.
- // This is a function installed by AEInstallEventHandler.
- // Guide Script:
- // <Define Event> "OpenNewDocument", 'AGS2', 'agse', 'agsw'
- // <Define Event> "CloseDocument", 'AGS2', 'agse', 'agsx'
- // For this sample application:
- // target app is 'AGS2' (kAGSTargetAppSignature).
- // event class is 'agse' (kAGSAEventClass).
- // event id is 'agsw' (kAGSAEventOpenNewDocument) and 'agsx' (kAGSAEventCloseDocument).
-
- pascal OSErr
- AGSHandleAEvents(AppleEvent* pAppleEvent,
- AppleEvent* /*theReply*/, long refCon)
- {
- OSType eventId;
- Size actualSize;
- DescType returnedType;
- WindowPtr pWin;
- Boolean isFound=false;
- OSErr err=noErr;
- // Get event id.
- err = AEGetAttributePtr(pAppleEvent, keyEventIDAttr,
- typeType, &returnedType,
- (Ptr) &eventId, sizeof(eventId),
- &actualSize);
- // Do event.
- switch (eventId)
- {
- case kAGSAEventOpenNewDocument:
- // Open new document
- err = NewDocument(&ghFileRec, kAGSDocSFType, true);
- if(err==noErr)
- err = DoNewWindow(ghFileRec, &pWin, nil, (WindowPtr)-1);
- break;
- case kAGSAEventCloseDocument:
- // Close front document
- for(pWin=nil; (pWin=GetNextDocumentWindow(pWin, 0))!=nil && !isFound;)
- if(pWin)
- if(((WindowPeek)pWin)->hilited)
- {
- (void) DisposeOneWindow(pWin, false);
- isFound = true;
- }
- break;
- default:
- err = errAEEventNotHandled;
- break;
- }
- return err;
- }
-
- // ---------- Open Functions ----------------------------------------------
-
- // ------------------------------------------------------------------------
- // OpenGuide
- // Open the default guide file.
-
- OSErr
- AGSOpenGuide()
- {
- FSSpec *pFileSpec=nil; // Want first guide file of type Help.
- UInt32 flags=0;
- Handle hMixinControl=nil;
- return AGOpen(pFileSpec, flags, hMixinControl, &gGuideRefNum);
- }
-
- // ------------------------------------------------------------------------
- // AGSOpenGuideWithSearch
- // Open the guide file with search.
- // Use the search phrase whose index is given.
- // We could do a simple open of the guide file with a search string,
- // but we elect to keep the search strings as a STR# resource in
- // the guide file. As a result, the application doesn't need to
- // know or maintain the strings, but can refer to them by an index.
- // The strings are maintained by the guide author and stored
- // in the guide using a <resource> command.
- // This also gives us a chance to show a use for AGFileLib.
-
- OSErr
- AGSOpenGuideWithSearch(short searchPhraseIndex)
- {
- FSSpec *pFileSpec=nil;
- UInt32 flags=0;
- Handle hMixinControl=nil;
- Boolean wantMixin=false;
- Str255 pSearchPhrase;
- FSSpec fileSpec;
- short vRefNum;
- long dirID;
- short guideRefNum;
- OSErr result;
- // Get the file spec for this application.
- result = AGSGetAppFSSpec(&fileSpec);
- if(result==noErr)
- {
- vRefNum = fileSpec.vRefNum;
- dirID = fileSpec.parID;
- // Use AGFileLib to get the file spec
- // for the first guide file of guide type HELP.
- result = AGFileGetIndDB(vRefNum, dirID, kAGFileDBTypeHelp,
- wantMixin, 1, &fileSpec);
- if(result==noErr)
- {
- // Open guide file resource fork.
- guideRefNum = FSpOpenResFile(&fileSpec, fsRdPerm);
- if(guideRefNum!=-1)
- {
- // Get search phrase from guide file resource fork.
- GetIndString(pSearchPhrase, kAGSSearchPhraseID, searchPhraseIndex);
- // Done with guide file.
- (void) FSClose(guideRefNum);
- // Open guide file with search phrase.
- if(pSearchPhrase[0]>0)
- result = AGOpenWithSearch(&fileSpec, flags, hMixinControl,
- pSearchPhrase, &gGuideRefNum);
- }
- }
- }
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSGetAppFSSpec
- // Returns the FSSpec of this application.
- // We use this to establish the path for the associated guide file.
- //
- OSErr
- AGSGetAppFSSpec(FSSpec* pFileSpec)
- {
- ProcessSerialNumber currentProcess;
- ProcessInfoRec infoRec;
- OSErr result;
-
- currentProcess.highLongOfPSN = 0;
- currentProcess.lowLongOfPSN = kCurrentProcess;
- infoRec.processInfoLength = sizeof(infoRec);
- infoRec.processName = nil;
- infoRec.processAppSpec = pFileSpec;
- result = GetCurrentProcess(¤tProcess);
- if(result==noErr)
- result = GetProcessInformation(¤tProcess, &infoRec);
- return result;
- }
-
- // ---------- AppleScript Coach Functions ---------------------------------
-
- // ------------------------------------------------------------------------
- // AGSInstallASCoachHandlers
- // Install the handlers for AppleScript Coach
-
- OSErr
- AGSInstallASCoachHandlers()
- {
- OSErr result;
- // Apple event handler
- result = AEInstallEventHandler(kAECoreSuite,
- kAEGetData,
- NewAEEventHandlerProc(AGSHandleGetData),
- kAEGetData,
- false);
- if(result!=noErr)
- return result;
- // Object accessors
- result = AEObjectInit();
- if(result!=noErr)
- return result;
- result = AEInstallObjectAccessor(cAGSASCoachItem, typeNull,
- NewOSLAccessorProc(AGSCoachItemAccessor),
- nil,
- false);
- if(result!=noErr)
- return result;
- result = AEInstallObjectAccessor(cProperty, cAGSASCoachItem,
- NewOSLAccessorProc(AGSCoachItemPropertyAccessor),
- nil,
- false);
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSRemoveASCoachHandlers
- // Remove the handlers for AppleScript Coach
-
- OSErr
- AGSRemoveASCoachHandlers()
- {
- OSErr result;
- // Apple event handler
- result = AERemoveEventHandler(kAECoreSuite, kAEGetData,
- nil, false);
- if(result!=noErr)
- return result;
- // Object accessors
- result = AERemoveObjectAccessor(cAGSASCoachItem, typeNull,
- nil, false);
- if(result!=noErr)
- return result;
- result = AERemoveObjectAccessor(cProperty, cAGSASCoachItem,
- nil, false);
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSHandleGetData
- // Return a reply to the Get Data Apple Event for the requested data.
- // The error, if any, is returned as a result.
-
- pascal OSErr
- AGSHandleGetData(AppleEvent* theAppleEvent,
- AppleEvent* reply,
- long refCon)
- {
- OSErr result=noErr;
- DescType reqType;
- Size theSize;
- AEDesc target;
- target.descriptorType = typeNull;
- target.dataHandle = nil;
- // First, get the direct object.
- result = AEGetParamDesc(theAppleEvent, keyDirectObject,
- typeObjectSpecifier, &target);
- if(result==noErr)
- {
- // Next, get the requested return type, if it exists.
- result = AEGetParamPtr(theAppleEvent, keyAERequestedType, typeType, &reqType,
- (Ptr)&reqType, sizeof(DescType), &theSize);
- if(result == errAEDescNotFound)
- {
- // not an error if return type is not found
- result = noErr;
- reqType = typeWildCard;
- }
- if(result==noErr)
- {
- // check for missing params
- result = AGSIsMissingParams(theAppleEvent);
- if(result==noErr)
- {
- AEDesc token; // direct object and resolved token.
- AEDesc objectData; // object data.
- token.descriptorType = typeNull;
- token.dataHandle = nil;
- objectData.descriptorType = typeNull;
- objectData.dataHandle = nil;
- // Resolve the object specifier
- // and get the token containing the property and container.
- result = AEResolve(&target, kAEIDoMinimum, &token);
- if(result==noErr)
- {
- // The container is nil for the application.
- if(token.dataHandle!=nil)
- result = AGSGetDataItemCoachRect(&token, &objectData);
- else
- result = errAEEventNotHandled;
- AEDisposeDesc(&token);
- }
- if(result==noErr && reply->dataHandle!=nil)
- {
- // Add data to the reply Apple event record.
- if (reqType != typeWildCard
- && reqType != typeBest
- && reqType != objectData.descriptorType)
- {
- // Do not use the same descriptor
- // as source and dest in AECoerceDesc().
- // This routine creates a copy of the source,
- // and then it is impossible to dispose of the memory
- // originally contained in the source's dataHandle.
- AEDesc tempDesc; // coerced data
- result = AECoerceDesc(&objectData, reqType, &tempDesc);
- AEDisposeDesc(&objectData);
- objectData.descriptorType = tempDesc.descriptorType;
- objectData.dataHandle = tempDesc.dataHandle;
- }
- if(result==noErr)
- result = AEPutParamDesc(reply, keyAEResult, &objectData);
- }
- AEDisposeDesc(&objectData);
- }
- }
- }
- AEDisposeDesc(&target);
-
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSGetDataItemCoachRect
- // Get the property data for the item and return it in the result parameter.
- // The result token contains the property type in the descriptorType field, and
- // a nil value in the dataHandle field to represent the null application.
-
- OSErr
- AGSGetDataItemCoachRect(AEDesc* token, AEDesc* pResult)
- {
- DescType theProperty=token->descriptorType;
- long coachItemIdentifier=(long) **(DescType**)token->dataHandle;
- Boolean isFound=false;
- WindowPtr pWin;
- Rect globalRect;
- OSErr result=noErr;
-
- switch (theProperty)
- {
- case pAGSASCoachRect:
- // Initialize the rect to an empty rect.
- SetRect(&globalRect, 0, 0, 0, 0);
- // Check each document window.
- for(pWin=nil; (pWin=GetNextDocumentWindow(pWin, 0))!=nil && !isFound;)
- if(pWin)
- if(((WindowPeek)pWin)->hilited)
- {
- // We only coach if the window is front (active).
- // Get the window content rectangle.
- Rect winRect = GetWindowContentRect(pWin);
- // Get the control whose ID==myNameAsDecNumber.
- ControlHandle hCtrl;
- (void) CNum2Ctl(pWin, coachItemIdentifier, &hCtrl);
- if(hCtrl)
- {
- // Get the local rect of the control and convert to global.
- Rect ctrlRect = (**hCtrl).contrlRect;
- globalRect.top = ctrlRect.top + winRect.top;
- globalRect.left = ctrlRect.left + winRect.left;
- globalRect.bottom = winRect.top + ctrlRect.bottom;
- globalRect.right = winRect.left + ctrlRect.right;
- isFound = true;
- }
- }
- // If you want the coach mark drawn, return noErr.
- // If you don't want the coach mark drawn, return kAGErrItemNotFound.
- if(isFound)
- {
- // Create an AEDesc returning the global rectangle for the object.
- result = AECreateDesc(typeQDRectangle, &globalRect,
- sizeof(globalRect), pResult);
- }
- else
- result = kAGErrItemNotFound;
- break;
-
- default: // We don't handle the requested property.
- result = errAEEventNotHandled;
- }
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSCoachItemAccessor
- // Return the token for the coach item identifier.
- // In our sample, we pass a number identifying the item to coach.
- // If you want to pass a string, use AGSDescToPString
- // instead of AGSDescToLong.
-
- pascal OSErr
- AGSCoachItemAccessor( DescType desiredClass,
- AEDesc* containerToken,
- DescType containerClass,
- DescType keyForm,
- AEDesc* keyData,
- AEDesc* resultToken,
- long refCon)
- {
- OSErr result=noErr;
- long coachItemIdentifier;
- switch (keyForm)
- {
- case formName:
- // coachItem name - get the name from the keyData.
- // We could coerce the name to a PString,
- // but since we're using numeric identifiers,
- // we coerce the name to a long.
- result = AGSDescToLong(keyData, &coachItemIdentifier);
- break;
-
- default:
- result = errAEEventNotHandled;
- }
- if(result==noErr)
- result = AECreateDesc(cAGSASCoachItem, (Ptr)&coachItemIdentifier,
- sizeof(coachItemIdentifier), resultToken);
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSCoachItemPropertyAccessor
- // Return a token representing the property for the coach item.
- // The storage object is referenced by the containerToken dataHandle.
- // The token is returned with the property and the storage object.
- // Note the casting required to get the storage object.
-
- pascal OSErr
- AGSCoachItemPropertyAccessor( DescType desiredClass,
- AEDesc* containerToken,
- DescType containerClass,
- DescType keyForm,
- AEDesc* keyData,
- AEDesc* resultToken,
- long refCon)
- {
- OSErr result=noErr;
- // Let's make sure we're accessing a valid descriptor type.
- // If formPropertyID, keyData descriptorType is typeType.
- // If formUserPropertyID, keyData descriptorType is defined in aete.
- if (desiredClass != cProperty
- || !(keyForm == formPropertyID || keyForm == formUserPropertyID))
- result = errAEWrongDataType;
- else if(!(containerToken->descriptorType==cAGSASCoachItem))
- result = errAETypeError;
- else
- {
- long coachItemIdentifier = (long) **(DescType**)containerToken->dataHandle;
- // Get the property type.
- DescType requestedProperty = **(DescType**)keyData->dataHandle;
- result = AECreateDesc(requestedProperty, (Ptr)&coachItemIdentifier,
- sizeof(coachItemIdentifier), resultToken);
- }
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSIsMissingParams
- // Check to see if there exists any additional parameters in the Apple Event.
- // If so, return an error to the calling routine.
-
- OSErr
- AGSIsMissingParams(AppleEvent* theAppleEvent)
- {
- DescType theType;
- Size actualSize;
- OSErr err;
-
- err = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
- &theType, nil, 0, &actualSize);
- if (err == errAEDescNotFound)
- err = noErr;
- else
- err = errAEEventNotHandled;
- return err;
- }
-
- // ------------------------------------------------------------------------
- // AGSDescToLong
- // Converts a descriptor to a long.
-
- OSErr
- AGSDescToLong(const AEDesc* desc, long* pLongValue)
- {
- AEDesc tempDesc;
- OSErr result=noErr;
-
- tempDesc.descriptorType = typeNull;
- tempDesc.dataHandle = nil;
- // If we have a typeLongInteger, use as-is. Otherwise coerce.
- if (desc->descriptorType == typeLongInteger)
- tempDesc.dataHandle = desc->dataHandle;
- else
- result = AECoerceDesc(desc, typeLongInteger, &tempDesc);
- if(result==noErr)
- {
- Handle dataHandle = tempDesc.dataHandle;
- // Copy long from dereferenced data handle
- // to dereferenced long pointer.
- *pLongValue = **(long**)dataHandle;
- }
- AEDisposeDesc(&tempDesc);
-
- return result;
- }
-
- // ------------------------------------------------------------------------
- // AGSDescToPString
- // Converts a descriptor to a pascal string.
- // This function is not used in the sample,
- // but you can use it if you pass a string instead of a number
- // to identify the item to coach.
-
- OSErr
- AGSDescToPString(const AEDesc* desc, StringPtr pStr, short maxLength)
- {
- AEDesc tempDesc;
- Handle dataHandle;
- long charCount;
- OSErr result=noErr;
- // If we have typeChar, use as-is. Otherwise coerce to typeChar.
- tempDesc.descriptorType = typeNull;
- tempDesc.dataHandle = nil;
- if (desc->descriptorType == typeChar)
- dataHandle = desc->dataHandle;
- else
- {
- result = AECoerceDesc(desc, typeChar, &tempDesc);
- if(result==noErr)
- dataHandle = tempDesc.dataHandle;
- }
- if(result==noErr)
- {
- charCount = GetHandleSize(dataHandle);
- if (charCount > maxLength)
- {
- result = errAECoercionFail;
- }
- if(result==noErr)
- {
- pStr[0] = charCount;
- HLock(dataHandle);
- BlockMoveData(*dataHandle, &pStr[1], charCount);
- HUnlock(dataHandle); // This may be from desc, so must unlock.
- }
- }
- AEDisposeDesc(&tempDesc);
-
- return result;
- }
-
- // ---------- Apps-To-Go Functions ---------------------------------
-
- // These functions were taken from Apps-To-Go
- // and lightly customized for the Apple Guide sample application.
- // They are not required for Apple Guide integration.
-
- // ------------------------------------------------------------------------
- // ContentClick
- // From Window.c
- /* •• You don't call this. DTS.Lib..framework does for appropriate document type(s). •• */
- /* This is called (by DoContentClick()) when a mouse-down event occurs in the content of
- ** a window. Other applications might want to call FindControl, TEClick, etc., to
- ** further process the click. */
-
- void
- ContentClick(WindowPtr window, EventRecord *event, Boolean firstClick)
- {
- ControlHandle ctl;
- short action, cnum;
-
- #pragma unused firstClick
-
- cnum = IsCtlEvent(window, event, &ctl, &action);
- /* That was easy. Scrolling was just handled. Other stuff would be handled
- ** by IsCtlEvent, if we had other stuff to do. We don't have any other
- ** controls in the content besides the document scrollbars. */
- // The two case statements were added for AGSample.
- switch (cnum)
- {
- case kAGSOpenGuideId:
- (void) AGSOpenGuide();
- break;
- case kAGSOpenGuideWithSearchId:
- (void) AGSOpenGuideWithSearch(1);
- break;
- default:
- break;
- }
-
- return;
- }
-
- #ifdef applec
- #pragma segment Main
- #endif
-
- // ------------------------------------------------------------------------
- // main
- // From Start.c
- // Removed a few unnecessary functions.
-
- void
- main(void)
- {
-
- #ifdef applec
- UnloadSeg((Ptr)_DataInit); /* Note that _DataInit can't be in Main! */
- #endif
-
- SetApplLimit(GetApplLimit() - 16384);
- /* This decreases the application heap by 16k, which in turn
- ** increases the stack by 16k. */
- MaxApplZone(); /* Expand the heap so code segments load at the top. */
- InitATGLIB();
- Initialize(32, kMinHeap, kMinSpace, nil, nil); /* Initialize the program. */
- DoSetResCursor(watchCursor); /* Rest of startup may take a while. */
- InitRequiredAppleEvents();
- DoOpenApplication(); /* Now must be in front of GetWindowFormats call. */
- GetWindowFormats(); /* Get the window definition resource information. */
- OpenRuntimeOnlyAutoNewWindows();
- DoAdjustMenus();
- UnloadSeg((Ptr)Initialize); /* Initialize can't be in Main! */
-
- AGSInstall(); // Added for AGSample
- EventLoop(); /* Call the main event loop. */
- AGSRemove(); // Added for AGSample
-
- ExitToShell(); /* Quit the application. */
- }
-
-